package mgodb

import (
	"jgt-oper/src/model"
	"jgt-oper/src/schema"
	"jgt-oper/src/service/mongo"
	"time"

	"github.com/facebookgo/inject"
	"github.com/globalsign/mgo"
	"github.com/globalsign/mgo/bson"
	"github.com/pkg/errors"
)

// cEnterprise 存储内容:企业基本信息、企业和门牌的的对应关系
const cEnterprise = "oper_enterprise"

// Enterprise 企业管理
type Enterprise struct {
	DB *mongo.DB
}

// Init 初始化
func (a *Enterprise) Init(g *inject.Graph, db *mongo.DB) {
	a.DB = db

	// 初始化mongo索引
	a.DB.C(cEnterprise, func(c *mgo.Collection) error {
		c.EnsureIndex(mgo.Index{
			Key:    []string{"record_id"},
			Unique: true,
		})
		c.EnsureIndexKey("name")
		c.EnsureIndexKey("deleted")
		c.EnsureIndexKey("deleted", "status")
		return nil
	})

	var val model.IEnterprise = a
	g.Provide(&inject.Object{Value: val, Name: "IEnterprise"})
}

// QueryPage 查询分页数据
func (a *Enterprise) QueryPage(params *schema.EnterpriseQueryParam, pageIndex, pageSize uint) (int, []*schema.Enterprise, error) {
	query := bson.M{
		"deleted": 0,
	}

	if v := params.Status; v != 0 {
		query["status"] = v
	}
	if v := params.IsHot; v != 0 {
		query["is_hot"] = v
	}
	if v := params.Name; v != "" {
		query["name"] = bson.M{"$regex": v}
	}
	if v := params.Contacts; v != "" {
		query["contacter"] = bson.M{"$regex": v}
	}
	if v := params.ContactTel; v != "" {
		query["contact_tel"] = bson.M{"$regex": v}
	}
	if v := params.Address; v != "" {
		query["address"] = bson.M{"$regex": v}
	}
	if v := params.Category; len(v) > 0 {
		query["category"] = bson.M{"$in": v}
	}
	if start, end := params.EntryTimeStart, params.EntryTimeEnd; start != 0 && end != 0 {
		query["$and"] = []bson.M{
			{"entry_time": bson.M{"$gte": start}},
			{"entry_time": bson.M{"$lte": end}},
		}
	}
	if start, end := params.MigrationTimeStart, params.MigrationTimeEnd; start != 0 && end != 0 {
		query["$and"] = []bson.M{
			{"migration_time": bson.M{"$gte": start}},
			{"migration_time": bson.M{"$lte": end}},
		}
	}

	var total int
	var items []*schema.Enterprise
	var err error
	err = a.DB.C(cEnterprise, func(c *mgo.Collection) error {
		total, err = c.Find(query).Count()
		if err != nil {
			return err
		}

		return c.Find(query).Sort("-_id").Skip(int((pageIndex - 1) * pageSize)).Limit(int(pageSize)).All(&items)
	})
	if err != nil {
		return 0, nil, errors.Wrapf(err, "查询分页数据发生错误")
	}

	return total, items, nil
}

// QueryMobilePage 查询移动端分页数据
func (a *Enterprise) QueryMobilePage(params schema.EnterpriseMobileQueryParam, pageSize uint) ([]*schema.EnterpriseMobileQueryResult, error) {
	query := bson.M{
		"deleted": 0,
		"status":  1,
	}

	if v := params.Category; v != "" {
		query["category"] = v
	}

	if v := params.IsHot; v == 1 {
		query["is_hot"] = 1
	}

	if v := params.LastID; v > 0 {
		query["_id"] = bson.M{"$gt": v}
	}

	if v := params.Name; v != "" {
		query["name"] = bson.M{"$regex": v}
	}

	var items []*schema.EnterpriseMobileQueryResult
	err := a.DB.C(cEnterprise, func(c *mgo.Collection) error {
		return c.Find(query).Sort("_id").Limit(int(pageSize)).All(&items)
	})
	if err != nil {
		return nil, errors.Wrapf(err, "查询分页数据发生错误")
	}
	return items, nil
}

// QuerySelect 查询选择数据
func (a *Enterprise) QuerySelect(name string) ([]*schema.EnterpriseSelect, error) {
	query := bson.M{
		"deleted": 0,
		"status":  1,
	}

	if name != "" {
		query["name"] = bson.M{"$regex": name}
	}
	var items []*schema.EnterpriseSelect
	err := a.DB.C(cEnterprise, func(c *mgo.Collection) error {
		return c.Find(query).Sort("_id").Limit(20).All(&items)
	})
	if err != nil {
		return nil, errors.Wrapf(err, "查询选择数据发生错误")
	}
	return items, nil
}

// Get 精确查询数据
func (a *Enterprise) Get(recordID string) (*schema.Enterprise, error) {
	var item schema.Enterprise
	err := a.DB.C(cEnterprise, func(c *mgo.Collection) error {
		return c.Find(bson.M{"record_id": recordID}).One(&item)
	})
	if err != nil {
		if err == mgo.ErrNotFound {
			return nil, nil
		}
		return nil, errors.Wrapf(err, "精确查询数据发生错误")
	}
	return &item, nil
}

// CheckName 检查名称是否存在
func (a *Enterprise) CheckName(name string) (bool, error) {
	var exists bool
	err := a.DB.C(cEnterprise, func(c *mgo.Collection) error {
		n, err := c.Find(bson.M{"deleted": 0, "name": name}).Count()
		if err != nil {
			return err
		}
		exists = n > 0
		return nil
	})
	if err != nil {
		return false, errors.Wrapf(err, "检查名称是否存在发生错误")
	}

	return exists, nil
}

// Create 企业入驻，创建数据
func (a *Enterprise) Create(item *schema.Enterprise) error {
	err := a.DB.C(cEnterprise, func(c *mgo.Collection) error {
		id, err := a.DB.IncrID(cEnterprise)
		if err != nil {
			return err
		}
		item.ID = id
		return c.Insert(item)
	})
	if err != nil {
		return errors.Wrapf(err, "创建数据发生错误")
	}

	return nil
}

// Update 更新数据...更新迁出状态和时间
func (a *Enterprise) Update(recordID string, info map[string]interface{}) error {
	err := a.DB.C(cEnterprise, func(c *mgo.Collection) error {
		return c.Update(bson.M{"record_id": recordID}, bson.M{"$set": info})
	})
	if err != nil {
		return errors.Wrapf(err, "更新数据发生错误")
	}
	return nil
}

// Delete 删除数据
func (a *Enterprise) Delete(recordID string) error {
	info := map[string]interface{}{
		"deleted": time.Now().Unix(),
	}
	err := a.DB.C(cEnterprise, func(c *mgo.Collection) error {
		return c.Update(bson.M{"record_id": recordID}, bson.M{"$set": info})
	})
	if err != nil {
		return errors.Wrapf(err, "删除数据发生错误")
	}
	return nil
}
